package com.blensmile.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.blensmile.R;

/**
 * Created by BlenSmile on 2017/1/16.
 */
public class EdgeLineImageView extends ImageView {

    private Paint paint;
    private Paint paint2;

    private int roundWidth = 10;
    private int roundHeight = 10;
    private int edgeWidth = 1;
    private @ColorInt int edgeColor = 0xffff00ff;
    private int width;
    private int height;

    public EdgeLineImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs);
    }

    public EdgeLineImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public EdgeLineImageView(Context context) {
        super(context);
        init(context, null);
    }

    private void init(Context context, AttributeSet attrs) {
        float density = context.getResources().getDisplayMetrics().density;
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundAngleImageView);
            roundWidth = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundWidth, (int)( density*roundWidth));
            roundHeight = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundHeight,(int)( density* roundHeight));
            edgeWidth = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_edgeWidth,edgeWidth);
            edgeColor = a.getColor(R.styleable.RoundAngleImageView_edgeColor,edgeColor);
        } else {
            roundWidth = (int) (roundWidth * density);
            roundHeight = (int) (roundHeight * density);
            edgeWidth = (int)(edgeWidth*density);
        }
        paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
//        paint.setColor(edgeColor);
        paint.setAntiAlias(true);
//        paint.setStrokeWidth(edgeWidth);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));

        paint2 = new Paint();
//        paint2.setXfermode(null);
        int abc = edgeWidth;
        setPadding(getPaddingLeft()+abc,getPaddingTop()+abc,getPaddingRight()+abc,getPaddingBottom()+abc);
    }

//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        width = MeasureSpec.getSize(widthMeasureSpec);
//        height = MeasureSpec.getSize(heightMeasureSpec);
//    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    public void draw(Canvas canvas) {
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas2 = new Canvas(bitmap);
//        drawRect(canvas2);
        super.draw(canvas2);
//        drawLiftUp(canvas2);
//        drawLiftUp(canvas2);
//        drawRightUp(canvas2);
//        drawLiftDown(canvas2);
//        drawRightDown(canvas2);
        drawRoundRect(canvas2);
        canvas.drawBitmap(bitmap, 0, 0, paint2);
        bitmap.recycle();
        drawEdge(canvas);
    }

    private void drawRect(Canvas canvas){
        Paint p = new Paint();
        p.setColor(edgeColor);
        p.setStrokeWidth(edgeWidth);
        p.setStyle(Paint.Style.STROKE);
        Path path = new Path();
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        canvas.drawRect(getRectF(pl,pt,width-pr,height-pb),p);
    }

    private void drawEdge(Canvas canvas2) {
        Paint p = new Paint();
//        p.setAntiAlias(true);
        p.setColor(edgeColor);
        p.setStrokeWidth(edgeWidth);
        p.setStyle(Paint.Style.STROKE);
        p.setAntiAlias(true);
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
//        canvas2.drawArc(getRectF(pl,pt,pl+roundWidth*2,pt+roundHeight*2),-90,-90,false,p);
//        canvas2.drawLine(pl,pt+roundHeight,pl,height-pb-roundHeight,p);
//        canvas2.drawArc(getRectF(pl,height-2*roundHeight-pb,pl+roundWidth*2,height-pb),180,-90,false,p);
//        canvas2.drawLine(pl+roundWidth,height-pb,width-pr-roundWidth,height-pb,p);
//        canvas2.drawArc(getRectF(width-pr-2*roundWidth,height-2*roundHeight-pb,width-pr,height-pb),90,-90,false,p);
//        canvas2.drawLine(width-pr,height-pb-roundHeight,width-pr,pt+roundHeight,p);
//        canvas2.drawArc(getRectF(width-pr-2*roundWidth,pt,width-pr,pt+2*roundHeight),0,-90,false,p);
//        canvas2.drawLine(pl+roundWidth,pt,width-pr-roundWidth,pt,p);
        canvas2.drawRoundRect(getRectF(pl,pt,width-pr,height-pb),roundWidth,roundHeight,p);
    }


    private RectF getRectF(int l,int t,int r,int b){
        int pen  = edgeWidth/2;
        return new RectF(l-pen,t-pen,r+pen,b+pen);
    }

    //方法3,成功,非常简洁
    private void drawRoundRect(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();
        path.addRoundRect(new RectF(pl,pt,width-pr,height-pb),roundWidth,roundHeight, Path.Direction.CW);
        path.setFillType(Path.FillType.INVERSE_EVEN_ODD);
        canvas.drawPath(path, paint);
    }

    //方法2,失败,arcTo和addArc都是蛋疼的主
    private void drawRoundAngeles(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();

        //左上
        path.moveTo(pl+roundWidth, pt);
        path.arcTo(getRectF(pl,pt,pl+roundWidth*2,pt+roundHeight*2),-90,-90,true);
        path.moveTo(pl,pt+roundHeight);
        path.rLineTo(pl,height-roundHeight-pb);

        //左下
        path.moveTo(pl, height-roundHeight-pb);
        path.arcTo(getRectF(pl,height-2*roundHeight-pb,pl+roundWidth*2,height-pb),180,-90,true);
        path.moveTo(pl+roundWidth, height-pb);
        path.lineTo(width-roundWidth-pr, height-pb);

        //右下
        path.moveTo(width-roundWidth-pr, height-pb);
        path.arcTo(getRectF(width-pr-2*roundWidth,height-2*roundHeight-pb,width-pr,height-pb),90,-90,true);
        path.moveTo(width-pr, height-pb);
        path.lineTo(width-pr, pt+roundHeight);

        //右上
        path.moveTo(width-pr, pt+roundHeight);
        path.arcTo(getRectF(width-pr-2*roundWidth,pt,width-pr,pt+2*roundHeight),0,-90,true);
        path.moveTo(width-pr-roundWidth, pt);
        path.lineTo(pl+roundWidth,pt);


        path.close();
        canvas.drawPath(path, paint);
    }

    //方法1,成功,但是好繁琐
    private void drawLiftUp(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();
        path.moveTo(pl, roundHeight+pt);
        path.lineTo(pl,pt);
        path.lineTo(roundWidth+pl, pt);
        path.arcTo(getRectF(pl,pt,pl+roundWidth*2,pt+roundHeight*2),-90,-90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawLiftDown(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();
        path.moveTo(pl, height - roundHeight-pb);
        path.lineTo(pl, height-pb);
        path.lineTo(roundWidth+pl, height-pb);
        path.arcTo(getRectF(pl,height-2*roundHeight-pb,pl+roundWidth*2,height-pb),90,90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightDown(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();
        path.moveTo(width - roundWidth-pr, height-pb);
        path.lineTo(width-pr, height-pb);
        path.lineTo(width-pr, height - roundHeight-pb);
        path.arcTo(getRectF(width-pr-2*roundWidth,height-2*roundHeight-pb,width-pr,height-pb),0,90);
        path.close();
        canvas.drawPath(path, paint);
    }

    private void drawRightUp(Canvas canvas) {
        int pl = getPaddingLeft();
        int pr = getPaddingRight();
        int pt = getPaddingTop();
        int pb = getPaddingBottom();
        int pen  = edgeWidth/2;
        Path path = new Path();
        path.moveTo(width-pr, roundHeight+pt);
        path.lineTo(width-pr, pt);
        path.lineTo(width - roundWidth-pr, pt);
        path.arcTo(getRectF(width-pr-2*roundWidth,pt,width-pr,pt+2*roundHeight),-90,90);
        path.close();
        canvas.drawPath(path, paint);
    }

}

